Skip to content

DO NOT MERGE — CI proof for #63: deliberate label drift - #70

Closed
os-sam wants to merge 2 commits into
mainfrom
claude/issue-63-ci-proof
Closed

DO NOT MERGE — CI proof for #63: deliberate label drift#70
os-sam wants to merge 2 commits into
mainfrom
claude/issue-63-ci-proof

Conversation

@os-sam

@os-sam os-sam commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Throwaway. Opened only so GitHub Actions executes the new gate against a real mismatch, closed as soon as the run reports. Part of #63; the deliverable is #69.

This branch is #69's commit plus one line: ats_job.fields.status renamed from Status to Review status in src/objects/job.object.ts, while src/translations/en.ts still says Status. The expectation is that the lint step of CI fails naming objects.ats_job.fields.status.label, the bundle's value and the source's.

The point of this PR is that a check which only runs on a developer's laptop is not a gate. #69's history stays clean; this one carries the red run.


Generated by Claude Code

`src/translations/en.ts` restates the English labels that already exist
inline in the object, view, app, dashboard and dataset definitions, so the
two locale files diff line for line. Nothing checked that the restatement
was still true: rename a label in an object file and the bundle keeps
serving the old string to every English user, because a bundle entry wins
over the source label at runtime.

Measured before this change, on this tree: `pnpm validate`, `pnpm lint
--i18n-strict` and `pnpm typecheck` are all green with a drifted entry, and
green with a missing `en` entry too — `os i18n check` reports `en` at 100 %
(expected 1265 / translated 1265) because the source label counts as the
translation for the default locale. Coverage asks whether a key exists, not
whether it still says what the metadata says.

`scripts/check-i18n-source.mjs` asks the second question. It reads both
sides out of `dist/objectstack.json` and fails on a drifted value, a key
whose metadata is gone, and a source label the bundle never restates. The
source side is collected twice on purpose: `os i18n extract --json` is the
platform's own single definition of what is translatable, so a surface the
platform adds later arrives here for free; a local resolver covers the
view-nested text that walk does not address (a view's default `list`, its
`listViews` and its `formViews`). Together they resolve all 507 keys in
`en.ts` — every key is compared, none is skipped, and a key shape neither
collector knows fails as an orphan rather than passing quietly.

`pnpm lint` chains it, so CI and a laptop run it without a fourth command.
It runs its own `--self-test` first, on every run: seven assertions that the
comparator still reports a mismatch, an orphan and a gap, so the gate proves
in CI that it can fail. The real run refuses to report success when either
side came back empty, or when the artifact is older than `src/`.

Zero findings on this tree today: 507 bundle keys, 507 source labels, 507
compared, 769 platform `metadataForms.*` keys excluded.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PbJ5Cy9KDAzeQHo8bsMadG
DO NOT MERGE. Renames ats_job.fields.status from 'Status' to 'Review status'
in the source while src/translations/en.ts still says 'Status', so the CI run
on this branch executes pnpm check:i18n-source against a real mismatch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PbJ5Cy9KDAzeQHo8bsMadG

os-sam commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator Author

Done its job — run 8 failed at the lint step naming objects.ats_job.fields.status.label, the bundle's "Status" and the source's "Review status". Evidence quoted on #69. Closing and deleting the branch; the deliverable is #69.


Generated by Claude Code

@os-sam os-sam closed this Sep 7, 2026

os-sam commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator Author

This PR's red CI is the deliverable. Not to be fixed, not to be merged.

Recording that explicitly so no later pass — mine or an automated one — "drives it to green" and destroys the evidence.

Card #63's acceptance asked for two things a green run cannot show: that the new i18n source-parity gate bites, and that it bites in CI rather than only on a developer's laptop. This PR is that proof. I read the failing job (101836788834) and it fails for exactly the right reason:

◆ i18n source parity
  bundle keys (src/translations/en.ts)    507
  source labels collected                 507   (482 os i18n extract + 25 view-nested)
  compared, key present on both sides     507
  excluded: platform built-in keys        769   (metadataForms.* — Studio copy the platform packages ship)

  drifted — the bundle overrides the source label (1)
    objects.ats_job.fields.status.label
      bundle (en.ts)  "Status"
      source          "Review status"   [os i18n extract]

  1 i18n source-parity issue(s)
 ELIFECYCLE  Command failed with exit code 1.

That is the exact mutation the card named, caught by key, with both values printed and a non-zero exit. Three things about that output matter more than the failure itself:

  • 507 of 507 keys compared. Not "the ones the resolver happened to handle" — every key in the bundle has a source counterpart and every one is checked. A gate with invisible coverage is the defect class this card exists to close, so the count being printed on every run is part of the fix, not decoration.
  • 769 platform built-in keys excluded, and named. That is os i18n check counts the platform's 773 metadata-form keys against this app and double-counts action keys, so its percentage cannot be the release gate #60's population, correctly kept out of this app's ledger rather than silently swelling it.
  • The comparator has its own self-test7 assertions — the comparator still reports drift, orphans and gaps runs immediately before. A gate that has stopped detecting anything is the failure mode I have hit twice in this repository today; this one checks itself before it checks the bundle.

The real PR is #69. This branch exists only to make the CI run above exist, and I will close it once I have reviewed #69 — leaving the run, its logs and this comment as the permanent record.

Do not merge. Do not re-run. Do not fix the red.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants